import tkinter as tk
from tkinter import StringVar
from typing import Callable

from 其他.tk_base_widgets.entry_in_listbox import EntryInListbox


# 文本双击变输入框
class Label2Entry(tk.Label):
    def __init__(self, master,
                 str_var:StringVar,     # 同步变量到其他地方
                 limit_func:Callable[...,bool]=lambda:True,      # 输入函数限制text进行同步，符合条件才同步
                 complete_list: list[str] = None,  # 总字符串列表
                 layout='pack',
                 pack_kwargs=None,
                 grid_kwargs:dict=None,
                 **kwargs):
        super().__init__(master, **kwargs)
        # self.strTextVar = StringVar(value='空')
        if pack_kwargs is None:     # 参数预处理
            pack_kwargs = {}
        if grid_kwargs is None:
            grid_kwargs = {}
        if complete_list is None:
            complete_list = []

        self.layout = layout            # 布局方式与参数
        self.pack_kwargs = pack_kwargs
        self.grid_kwargs = grid_kwargs

        self.strTextVar = str_var
        self.func:Callable[...,bool] = limit_func     # 一个返回bool类型的参数


        self.bind('<Double-Button-1>', lambda e:self.show_entry())
        self.bind('Button-1', lambda e:self.focus_set())
        # 没有主界面，单独的界面与本label类同级。——————给entry增加listbox补全逻辑
        self.entry = EntryInListbox(textvariable=self.strTextVar,
                                    complete_list=complete_list)
        self.entry.bind('<FocusOut>', self.show_label)
        self.entry.bind('<Return>', self.show_label)
        self.entry.widget_layout_forget(self.entry)
        # 展示组件————内置布局底层
        self.widget_layout_show(self)

    # 自适应布局底层的方法
    def widget_layout_show(self,widget:tk.Widget=None):
        if self.layout in ('p','P','pack','PACK'):
            widget.pack(self.pack_kwargs)
        elif self.layout in ('g','G','grid','GRID'):
            widget.grid(self.grid_kwargs)

    def widget_layout_forget(self,widget:tk.Widget=None):
        if self.layout in ('p','P','pack','PACK'):
            widget.pack_forget()
        elif self.layout in ('g','G','grid','GRID'):
            widget.grid_forget()

    def show_entry(self):
        self.widget_layout_forget(self)
        self.widget_layout_show(self.entry)
        # self.pack_forget()
        # self.entry.pack()
        self.entry.focus_set()

    def show_label(self, event):
        # print(event,type(event),event.__dict__)
        if event.keycode == 13:     # 按下回车键
            self.entry._on_return()     # 执行子控件的回车键回调函数
        if self.is_fresh_label():      # 如果条件OK
            self.config(text=self.entry.get())  # 将label的值与entry的值进行同步
        # time.sleep(1)
        self.widget_layout_forget(self.entry)
        self.widget_layout_show(self)
        # self.entry.pack_forget()
        # self.pack()

    # 是否刷新label数值
    def is_fresh_label(self):
        return self.func()


if __name__ == '__main__':
    root = tk.Tk()
    root.geometry('300x300')
    l = ['assert', 'abcd', 'asvvv', 'asszert', 'asvaed']
    strVar = StringVar(value='')
    label = Label2Entry(root, text='文本',str_var=strVar, layout='p', pack_kwargs={'side':'top'}, width=40,complete_list=l)
    # label.pack()
    root.mainloop()



